/**
 * Projeto Myou - Disciplina: Sistemas de Informação I
 * @author Ronycley Gonçalves Agra
 * @since 23/09/2011
 */
package myou.classes;


import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * Classe sistema que serve de interface entre a camada de interface e lógica de
 * negócio. Funciona como a fusão entre o "Controller" e o "Model" no padrão
 * arquitetural MVC
 * 
 * @author Ronycley Gonçalves Agra
 * @version 1.00
 * @since Milestone 1 23/09/2011
 * @see myou.classes.Emprestimo
 * @see myou.classes.Interesse
 * @see myou.classes.Item
 * @see myou.classes.Mensagem
 * @see myou.classes.RequisicaoDeAmizade
 * @see myou.classes.RequisicaoDeEmprestimo
 * @see myou.classes.Sessao
 * @see myou.classes.Topico
 * @see myou.classes.Usuario
 */
public class Sistema {

	private static Calendar dataSitema;
	private Usuario usuario;
	private Item item;
	private List<Usuario> usuarios;
	private List<Item> itens;
	private List<Sessao> sessoes;
	private List<RequisicaoDeAmizade> requisicoes;
	private List<Emprestimo> emprestimos;
	private List<RequisicaoDeEmprestimo> requisicoesEmprestimo;
	private List<Topico> topicos;
	private List<Interesse> interesses;
	private HashMap<String,Integer> mapaEmprestimos;
	//private List<Atividade> atividades;

	/**
	 * Construtor
	 */
	public Sistema() {
		this.zerarSistema();
	}

	/**
	 * Prepara as listas usadas pelo sistema
	 */
	public void zerarSistema() {
		Sistema.dataSitema = new GregorianCalendar();
		this.usuarios = new ArrayList<Usuario>();
		this.itens = new ArrayList<Item>();
		this.sessoes = new ArrayList<Sessao>();
		this.requisicoes = new ArrayList<RequisicaoDeAmizade>();
		this.emprestimos = new ArrayList<Emprestimo>();
		this.requisicoesEmprestimo = new ArrayList<RequisicaoDeEmprestimo>();
		this.topicos = new ArrayList<Topico>();
		this.interesses = new ArrayList<Interesse>();
		this.mapaEmprestimos = new HashMap<String,Integer>();
		//this.atividades = new ArrayList<Atividade>();
	}

	/**
	 * Destroi as listas usadas internamente pelo sistema
	 */
	public void encerrarSistema() {
		this.usuarios = null;
		this.itens = null;
		this.sessoes = null;
		this.requisicoes = null;
		this.emprestimos = null;
		this.requisicoesEmprestimo = null;
		this.topicos = null;
		this.interesses = null;
		this.mapaEmprestimos = null;
	}

	/**
	 * Retorna uma sessão com o usuário recuperado a partir do login informado.
	 * 
	 * @param login
	 *            O login a ser pesquisado
	 * @return O id da sessão criada com o usuário recuperado a partir do login
	 *         informado
	 * @throws Exception
	 *             Lança exceção caso login seja nulo, branco ou não exista
	 *             usuário com o login informado
	 */
	public String abrirSessao(String login) throws Exception {
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		Iterator<Usuario> it = this.usuarios.iterator();
		while (it.hasNext()) {
			Usuario usuario = it.next();
			if (usuario.getLogin().equals(login)) {
				Sessao sessao = new Sessao(usuario);
				sessoes.add(sessao);
				return sessao.getId();
			}
		}
		throw new Exception("Usuário inexistente");
	}

	/**
	 * Retorna o valor do atributo de um usuário
	 * 
	 * @param login
	 *            O login do usuário
	 * @param atributo
	 *            O atributo desejado
	 * @return O valor do atributo
	 * @throws Exception
	 *             Lança exceção caso o login ou atributo sejam nulos ou
	 *             brancos, não exista o usuário com o login informado ou o
	 *             atributo seja inválido
	 */
	public String getAtributoUsuario(String login, String atributo)
			throws Exception {
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (atributo == null || atributo.equals("")) {
			throw new Exception("Atributo inválido");
		}
		Iterator<Usuario> it = this.usuarios.iterator();
		while (it.hasNext()) {
			Usuario usuario = it.next();
			if (usuario.getLogin().equals(login)) {
				if (atributo.equals("nome")) {
					return usuario.getNome();
				} else if (atributo.equals("endereco")) {
					return usuario.getEndereco();
				} else {
					throw new Exception("Atributo inexistente");
				}
			}
		}
		throw new Exception("Usuário inexistente");
	}

	/**
	 * Cadastra um item no sistema
	 * 
	 * @param idSessao
	 *            O id da sessão atual
	 * @param nome
	 *            O nome do item
	 * @param descricao
	 *            A descrição do item
	 * @param categoria
	 *            A categoria do item
	 * @return O id do novo item
	 * @throws Exception
	 *             Lança exceção caso o id da sessão, o nome do item, a
	 *             descrição do item ou a categoria do item sejam nulos ou
	 *             brancos, não exista a sessão com o id informado ou a
	 *             categoria seja inexistente.
	 */
	public String cadastrarItem(String idSessao, String nome, String descricao,
			String categoria) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (nome == null || nome.equals("")) {
			throw new Exception("Nome inválido");
		}
		if (categoria == null || categoria.equals("")) {
			throw new Exception("Categoria inválida");
		}
		if (categoria.equals("Livro") || categoria.equals("Filme")
				|| categoria.equals("Jogo")) {
			if (this.existeSessao(idSessao)) {
				Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
				Usuario usuario = usuarioSessao;
				this.usuarios.remove(usuarioSessao);
				item = new Item(usuario,nome, descricao, categoria);
				itens.add(item);
				usuario.addAtividade(usuario.getNome()+" cadastrou "+nome,null);
				this.usuarios.add(usuario);
				return item.getId();
			} else {
				throw new Exception("Sessão inexistente");
			}
		} else {
			throw new Exception("Categoria inexistente");
		}
	}

	/**
	 * Retorna o valor do atributo de um item
	 * 
	 * @param idItem
	 *            O id do item
	 * @param atributo
	 *            O atributo desejado
	 * @return O valor do atributo
	 * @throws Exception
	 *             Lança exceção caso o id do item ou o atributo sejam nulos ou
	 *             brancos, não exista o item com o id informado ou o atributo
	 *             seja inválido
	 * 
	 */
	public String getAtributoItem(String idItem, String atributo)
			throws Exception {
		if (idItem == null || idItem.equals("")) {
			throw new Exception("Identificador do item é inválido");
		}
		if (atributo == null || atributo.equals("")) {
			throw new Exception("Atributo inválido");
		}
		Iterator<Item> it = this.itens.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (item.getId().equals(idItem)) {
				if (atributo.equals("nome")) {
					return item.getNome();
				} else if (atributo.equals("descricao")) {
					return item.getDescricao();
				} else if (atributo.equals("categoria")) {
					return item.getCategoria();
				} else {
					throw new Exception("Atributo inexistente");
				}
			}
		}
		throw new Exception("Item inexistente");
	}

	/**
	 * Localiza um usuário no sistema
	 * 
	 * @param idSessao
	 *            O id da sessão atual
	 * @param chave
	 *            A chave a ser pesquisada
	 * @param atributo
	 *            O atributo a ser pesquisado
	 * @return O nome do usuário com o seu endereço
	 * @throws Exception
	 *             Lança exceção caso o id da sessão, a chave ou atributo sejam
	 *             nulos ou brancos, não exista a sessão com o id informado ou o
	 *             atributo seja inexistente
	 */
	public String localizarUsuario(String idSessao, String chave,
			String atributo) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (chave == null || chave.equals("")) {
			throw new Exception("Palavra-chave inválida");
		}
		if (atributo == null || atributo.equals("")) {
			throw new Exception("Atributo inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			String nomes = null;
			Iterator<Usuario> it = this.usuarios.iterator();
			while (it.hasNext()) {
				Usuario usuario = it.next();
				if (!usuario.equals(usuarioSessao)) {

					String valorStr = "";
					if (atributo.equals("nome")) {
						valorStr = usuario.getNome();
					} else if (atributo.equals("endereco")) {
						valorStr = usuario.getEndereco();
					} else {
						throw new Exception("Atributo inexistente");
					}
					if (valorStr.contains(chave)) {
						if (nomes == null) {
							nomes = usuario.getNome() + " - "
									+ usuario.getEndereco();
						} else {
							nomes = nomes + "; "+ usuario.getNome() + " - "
									+ usuario.getEndereco();
						}
					}
				}
			}
			if (nomes != null) {
				return nomes;
			} else {
				return "Nenhum usuário encontrado";
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Retorna as requisições de amizade do usuário da sessão informada
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @return O login dos usuários requisitantes
	 * @throws Exception
	 *             Lança exceção caso o id da sessão seja nulo ou branco ou não
	 *             exista a sessão com o id informado.
	 */
	public String getRequisicoesDeAmizade(String idSessao) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<RequisicaoDeAmizade> it = this.requisicoes.iterator();
			String nomes = null;
			while (it.hasNext()) {
				RequisicaoDeAmizade requisicao = it.next();
				if (requisicao.getRequisitado().equals(usuarioSessao)) {
					if (nomes == null) {
						nomes = requisicao.getRequisitante().getLogin();
					} else {
						nomes += "; " + requisicao.getRequisitante().getLogin();
					}
				}
			}
			if (nomes != null) {
				return nomes;
			} else {
				return "Não há requisições";
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Cria uma nova requisição de amizade
	 * 
	 * @param idSessao
	 *            O id da sessão do usuário requisitante
	 * @param login
	 *            O login do usuário requisitadp
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o login sejam nulos ou
	 *             brancos, não exista a sessão com o id informado, não exista
	 *             usuário com o login informado, os usuários requisitante já
	 *             seja amigo do usuário requisitado ou a requisição já foi
	 *             solicitada.
	 */
	public void requisitarAmizade(String idSessao, String login)
			throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario requisitado = this.getUsuario(login);
			if (requisitado == null) {
				throw new Exception("Usuário inexistente");
			}
			if (usuarioSessao.getAmigos().contains(requisitado)) {
				throw new Exception("Os usuários já são amigos");
			}
			RequisicaoDeAmizade requisicao = new RequisicaoDeAmizade(
					usuarioSessao, requisitado);
			if (this.contemRequisicao(requisicao)) {
				throw new Exception("Requisição já solicitada");
			}
			this.requisicoes.add(requisicao);
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Verifica se dois usuários já são amigos
	 * 
	 * @param idSessao
	 *            O id da sessão que contem o primeiro usuário
	 * @param login
	 *            O login do segundo usuário
	 * @return "True" caso os usuários já sejam amigos ou "False" caso contrário
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o login seja nulo ou
	 *             branco, não exista a sessão com o id informado ou não exista
	 *             usuário com o login informado.
	 */
	public String ehAmigo(String idSessao, String login) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario usuarioTeste = this.getUsuario(login);
			if (usuarioTeste == null) {
				throw new Exception("Usuário inexistente");
			}
			if (usuarioSessao.getAmigos().contains(usuarioTeste)) {
				return "true";
			} else {
				return "false";
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}
	
	/**
	 * Cria usuÃ¡rios no sistema
	 * 
	 * @param login
	 *            O login do usuÃ¡rio
	 * @param nome
	 *            O nome do usuÃ¡rio
	 * @param endereco
	 *            O endereÃ§o do usuÃ¡rio
	 * @throws Exception
	 *             LanÃ§a exceÃ§Ã£o caso o nome ou login sejam nulos ou brancos ou
	 *             jÃ¡ exista algum usuÃ¡rio com o login informado,
	 */
	public void criarUsuario(String login, String nome, String endereco)
			throws Exception {
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (nome == null || nome.equals("")) {
			throw new Exception("Nome inválido");
		}
		Iterator<Usuario> it = this.usuarios.iterator();
		while (it.hasNext()) {
			Usuario usuario = it.next();
			if (usuario.getLogin().equals(login)) {
				throw new Exception("Já existe um usuário com este login");
			}
		}

		this.usuario = new Usuario(login, nome, endereco);
		this.usuarios.add(usuario);
		this.mapaEmprestimos.put(usuario.getLogin(), new Integer(0));
		
	}

	/**
	 * @param idSessao
	 * @return String As atividades do usuário
	 * @throws Exception
	 */
	public String historicoAtividades(String idSessao) throws Exception{
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<Atividade> it = usuarioSessao.getAtividades().iterator();
			String mensagensAtividade = "";
			while (it.hasNext()) {
				Atividade atividade = it.next();
				if (mensagensAtividade.equals("")) {
					mensagensAtividade = atividade.getMensagemAtividade();
				} else {
					mensagensAtividade = mensagensAtividade + "; "+atividade.getMensagemAtividade();
				}
			}
			if(mensagensAtividade.equals("")){
				return "Não há atividades";
			}else{
				return mensagensAtividade;
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}
	
	/**
	 * @param idSessao
	 * @return String As atividades do usuário
	 * @throws Exception
	 */
	public String historicoAtividadesConjunto(String idSessao) throws Exception{
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			String mensagensAtividade = "";
			TreeSet<Atividade> atividadesConjuntas = new TreeSet<Atividade>(new ComparadorAtividade());
			TreeSet<Atividade> atividadesUsuarioSessao = usuarioSessao.getAtividades();
			Iterator<Atividade> it0 = atividadesUsuarioSessao.iterator();
			while (it0.hasNext()) {
				Atividade atUsuarioSessao = it0.next();
				atividadesConjuntas.add(atUsuarioSessao);
			}
			List<Usuario> amigos = usuarioSessao.getAmigos();
			Iterator<Usuario> it1 = amigos.iterator();
			while (it1.hasNext()) {
				Usuario amigo = it1.next();
				TreeSet<Atividade> atividadesAmigo = amigo.getAtividades();
				Iterator<Atividade> it2 = atividadesAmigo.iterator();
				while (it2.hasNext()) {
					Atividade atividadeAmigo = it2.next();
					atividadesConjuntas.add(atividadeAmigo);
				}
			}
			Iterator<Atividade> it = atividadesConjuntas.iterator();
			while (it.hasNext()) {
				Atividade atividade = it.next();
				if (mensagensAtividade.equals("")) {
					mensagensAtividade = atividade.getMensagemAtividade();
				} else {
					mensagensAtividade = mensagensAtividade + "; "+atividade.getMensagemAtividade();
				}
			}
			if(mensagensAtividade.equals("")){
				return "Não há atividades";
			}else{
				return mensagensAtividade;
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Aprova uma amizade que foi solicitada
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário requisitado
	 * @param login
	 *            O login do usuário requisitante
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o login seja nulo ou
	 *             branco, não exista a sessão com o id informado, não exista
	 *             usuário com o login informado ou os usuário já sejam amigos
	 */
	public void aprovarAmizade(String idSessao, String login) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario requisitante = this.getUsuario(login);
			if (requisitante == null) {
				throw new Exception("Usuário inexistente");
			}
			if (usuarioSessao.getAmigos().contains(requisitante)) {
				throw new Exception("Os usuários já são amigos");
			}

			RequisicaoDeAmizade requisicao = this.getRequisicaoDeAmizade(
					requisitante, usuarioSessao);
			if (requisicao == null) {
				throw new Exception("Requisição de amizade inexistente");
			}

			Usuario usuario1 = usuarioSessao;
			Usuario usuario2 = requisitante;
			this.usuarios.remove(usuarioSessao);
			this.usuarios.remove(requisitante);
			usuario1.addAmigo(requisitante);
			usuario2.addAmigo(usuarioSessao);
			GregorianCalendar data1 = new GregorianCalendar();
			Atividade atividade1 = new Atividade(data1,usuario1.getNome()+" e "+usuario2.getNome()+" são amigos agora",usuario1,usuario2);
			usuario1.addAtividade(atividade1);
			GregorianCalendar data2 = data1;
			data2.add(GregorianCalendar.MILLISECOND,1);
			Atividade atividade2 = new Atividade(data2,usuario2.getNome()+" e "+usuario1.getNome()+" são amigos agora",usuario1,usuario2);
			usuario2.addAtividade(atividade2);
			
			this.usuarios.add(usuario1);
			this.usuarios.add(usuario2);
			this.removerRequisicaoAmizade(requisitante, usuarioSessao);
		} else {
			throw new Exception("Sessão inexistente");
		}
	}
	
	public String publicarPedido(String idSessao, String nomeItem, String descricaoItem) throws Exception{
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (nomeItem == null || nomeItem.equals("")) {
			throw new Exception("Nome inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario usuario1 = usuarioSessao;
			this.usuarios.remove(usuarioSessao);
			//usuario1.addPedido(nomeItem,descricaoItem);
			this.usuarios.add(usuario1);
		} else {
			throw new Exception("Sessão inexistente");
		}
		return "";
	}

	/**
	 * Aprova um emprestimo solicitado anteriormente
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário requisitante
	 * @param idRequisicaoEmprestimo
	 *            O id da requisição de empréstimo
	 * @return O id do novo empréstimo
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id da requisição sejam
	 *             nulos ou brancos, não exista a sessão com o id informado, não
	 *             exista a requisição de empréstimo com o id informado, o
	 *             usuário requisitante não seja o dono do item ou empréstimo já
	 *             foi aprovado.
	 */
	public String aprovarEmprestimo(String idSessao,
			String idRequisicaoEmprestimo) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (idRequisicaoEmprestimo == null || idRequisicaoEmprestimo.equals("")) {
			throw new Exception(
					"Identificador da requisição de empréstimo é inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			RequisicaoDeEmprestimo requisicao = this
					.getRequisicaoEmprestimo(idRequisicaoEmprestimo);

			if (requisicao == null) {
				throw new Exception("Requisição de empréstimo inexistente");
			}

			if (!requisicao.getItem().getUsuario().equals(usuarioSessao)) {
				throw new Exception(
						"O empréstimo só pode ser aprovado pelo dono do item");
			}

			Item item = requisicao.getItem();
			Item itemEmprestado = item;
			itemEmprestado.setSituacao("Emprestado");
			this.itens.remove(item);
			this.itens.add(itemEmprestado);
			requisicao.setItem(itemEmprestado);
			Emprestimo emprestimo = new Emprestimo(requisicao.getItem()
					.getUsuario(), requisicao.getUsuario(), itemEmprestado,
					requisicao.getDuracao(), idRequisicaoEmprestimo);

			if (this.contemEmprestimo(emprestimo)) {
				throw new Exception("Empréstimo já aprovado");
			}

			usuarioSessao.addEmprestimo(emprestimo);
			this.emprestimos.add(emprestimo);
			this.removerInteresse(emprestimo.getBeneficiado(), emprestimo.getItem());
			Integer numeroEmprestimos = this.mapaEmprestimos.remove(emprestimo.getEmprestador().getLogin());
			this.mapaEmprestimos.put(emprestimo.getEmprestador().getLogin(), numeroEmprestimos.intValue()+1);
			Usuario usuario = usuarioSessao;
			usuario.addAtividade(usuario.getNome()+" emprestou "+itemEmprestado.getNome()+" a "+emprestimo.getBeneficiado().getNome(),
					emprestimo.getBeneficiado());
			this.usuarios.remove(usuarioSessao);
			this.usuarios.add(usuario);
			return emprestimo.getId();
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Devolve um item emprestado
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário beneficiado
	 * @param idEmprestimo
	 *            O id do empréstimo
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id do empréstimo sejam
	 *             nulos ou brancos, não exista a sessão com o id informado, não
	 *             exista o empréstimo com o id informado, o usuário da sessão
	 *             não seja o usuário beneficiado do empréstimo ou item já tenha
	 *             sido devolvido.
	 */
	public void devolverItem(String idSessao, String idEmprestimo)
			throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}

		if (this.existeSessao(idSessao)) {
			if (idEmprestimo == null || idEmprestimo.equals("")) {
				throw new Exception("Identificador do empréstimo é inválido");
			}

			if (this.getEmprestimo(idEmprestimo) == null) {
				throw new Exception("Empréstimo inexistente");
			}

			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();

			if (this.getEmprestimo(idEmprestimo) == null) {
				throw new Exception("Empréstimo inexistente");
			}

			Iterator<Emprestimo> it = this.emprestimos.iterator();
			while (it.hasNext()) {
				Emprestimo emprestimo = it.next();
				if (emprestimo.getId().equals(idEmprestimo)) {
					if (!emprestimo.getBeneficiado().equals(usuarioSessao)) {
						throw new Exception(
								"O item só pode ser devolvido pelo usuário beneficiado");
					}
					if (emprestimo.getItem().getSituacao().equals("Disponivel")) {
						throw new Exception("Item já devolvido");
					}
					// emprestimo.setSituacao("Devolvido");
					Emprestimo emprestimoDevolvido = emprestimo;
					Item item = emprestimoDevolvido.getItem();
					item.setSituacao("Disponivel");
					emprestimoDevolvido.setItem(item);
					// emprestimoDevolvido.setSituacao("Completado");
					this.emprestimos.remove(emprestimo);
					this.emprestimos.add(emprestimoDevolvido);
					break;
				}
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Confirma o término de um empréstimo.
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o dono do item
	 * @param idEmprestimo
	 *            O id do empréstimo
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id do empréstimo sejam
	 *             nulos ou brancos, não exista a sessão com o id informado, não
	 *             exista o empréstimo com o id informado, o usuário da sessão
	 *             não seja o dono do item do empréstimo ou o término do
	 *             empréstimo já tenha sido confirmado.
	 */
	public void confirmarTerminoEmprestimo(String idSessao, String idEmprestimo)
			throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (idEmprestimo == null || idEmprestimo.equals("")) {
			throw new Exception("Identificador do empréstimo é inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<Emprestimo> it = this.emprestimos.iterator();
			boolean encontrouEmprestimo = false;
			while (it.hasNext()) {
				Emprestimo emprestimo = it.next();
				if (emprestimo.getId().equals(idEmprestimo)) {
					encontrouEmprestimo = true;
					if (!emprestimo.getItem().getUsuario()
							.equals(usuarioSessao)) {
						throw new Exception(
								"O término do empréstimo só pode ser confirmado pelo dono do item");
					}
					if (emprestimo.getSituacao().equals("Completado")) {
						throw new Exception(
								"Término do empréstimo já confirmado");
					}
					if (!emprestimo.getSituacao().equals("Cancelado")) {
						emprestimo.setSituacao("Completado");
						Emprestimo emprestimoCompletado = emprestimo;
						Usuario emprestador = emprestimoCompletado.getEmprestador();
						Usuario emprestadorAlterado = emprestador;
						emprestadorAlterado.addAtividade(emprestadorAlterado.getNome()+" confirmou o término do empréstimo do item "+
								emprestimoCompletado.getItem().getNome(),null);
						this.usuarios.remove(emprestador);
						this.usuarios.add(emprestadorAlterado);
						emprestimoCompletado.setEmprestador(emprestadorAlterado);
						this.emprestimos.remove(emprestimo);
						this.emprestimos.add(emprestimoCompletado);
						this.removerRequisicaoEmprestimo(emprestimo
								.getIdRequisicao());
						this.enviarMensagemInteresse(emprestimo.getItem());
					}
					break;
				}
			}
			if (!encontrouEmprestimo) {
				throw new Exception("Empréstimo inexistente");
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Cria uma requisição de devolução de um item emprestado.
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário emprestador
	 * @param idEmprestimo
	 *            O id do empréstimo
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id do empréstimo sejam
	 *             nulos ou brancos, não exista a sessão com o id informado, não
	 *             exista o empréstimo com o id informado, o usuário da sessão
	 *             não seja o dono do item do empréstimo, o item já tenha sido
	 *             devolvido ou a devolução já tenho sido solicitada.
	 */
	public void requisitarDevolucao(String idSessao, String idEmprestimo)
			throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (idEmprestimo == null || idEmprestimo.equals("")) {
			throw new Exception("Identificador do empréstimo é inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Emprestimo emprestimo = this.getEmprestimo(idEmprestimo);
			if (emprestimo == null) {
				throw new Exception("Empréstimo inexistente");
			}
			if (!emprestimo.getEmprestador().equals(usuarioSessao)) {
				throw new Exception(
						"O usuário não tem permissão para requisitar a devolução deste item");
			}
			if (emprestimo.getItem().getSituacao().equals("Disponivel")) {
				throw new Exception("Item já devolvido");
			}
			if (emprestimo.getSituacao().equals("Cancelado")) {
				throw new Exception("Devolução já requisitada");
			}
			Emprestimo emprestimoAlterado = emprestimo;
			if (Sistema.getDataSistema().before(
					emprestimoAlterado.getDataEntrega())) {
				emprestimoAlterado.setSituacao("Cancelado");
				this.emprestimos.remove(emprestimo);
				this.emprestimos.add(emprestimoAlterado);
			}

			this.enviarMensagemRequisicaoDevolucao(emprestimoAlterado);
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Envia uma mensagem <i>'offtopic'<i> entre dois usuários
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário origem
	 * @param loginDestinatario
	 *            O login do usuário destino
	 * @param assunto
	 *            O assunto da mensagem (Tópico)
	 * @param conteudoMensagem
	 *            O conteúdo da mensagem
	 * @return O id do tópico
	 * @throws Exception
	 *             Lança exceção caso o id da sessão, o login do destinatário, o
	 *             assunto da mensagem ou o conteúdo sejam nulos ou brancos, não
	 *             exista a sessão com o id informado ou não exista o
	 *             destinatério com o login informado.
	 */
	public String enviarMensagem(String idSessao, String loginDestinatario,
			String assunto, String conteudoMensagem) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (loginDestinatario == null || loginDestinatario.equals("")) {
			throw new Exception("Destinatário inválido");
		}
		if (assunto == null || assunto.equals("")) {
			throw new Exception("Assunto inválido");
		}
		if (conteudoMensagem == null || conteudoMensagem.equals("")) {
			throw new Exception("Mensagem inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario usuarioDestinatario = this.getUsuario(loginDestinatario);
			if (usuarioDestinatario == null) {
				throw new Exception("Destinatário inexistente");
			}
			Mensagem mensagem = new Mensagem(usuarioSessao,
					usuarioDestinatario, conteudoMensagem);
			List<Usuario> usuariosTopico = new ArrayList<Usuario>();
			usuariosTopico.add(usuarioSessao);
			usuariosTopico.add(usuarioDestinatario);
			Topico topico = null;
			Iterator<Topico> it = this.topicos.iterator();
			boolean encontrouTopico = false;
			while (it.hasNext()) {
				Topico topicoIt = it.next();
				if (topicoIt.getAssunto().equals(assunto)
						&& topicoIt.getTipo().equals("offtopic")
						&& topicoIt.getUsuariosParticipantes().contains(
								usuarioSessao)
						&& topicoIt.getUsuariosParticipantes().contains(
								usuarioDestinatario)) {
					Topico topicoItmodificado = topicoIt;

					topicoItmodificado.addMensagem(mensagem);
					this.topicos.remove(topicoIt);
					this.topicos.add(topicoItmodificado);
					topico = topicoItmodificado;
					encontrouTopico = true;
					break;
				}
			}
			if (!encontrouTopico) {
				topico = new Topico(assunto, "offtopic", usuariosTopico);
				topico.addMensagem(mensagem);
				this.topicos.add(topico);
			}
			return topico.getId();
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Envia uma mensagem <i>'negociacao'<i> entre dois usuários
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário origem
	 * @param loginDestinatario
	 *            O login do usuário destino
	 * @param assunto
	 *            O assunto da mensagem (Tópico)
	 * @param conteudoMensagem
	 *            O conteúdo da mensagem
	 * @param idRequisicaoEmprestimo
	 *            O id da requisição do empréstimo.
	 * @return O id do tópico
	 * @throws Exception
	 *             Lança exceção caso o id da sessão, o login do destinatário, o
	 *             assunto da mensagem ou o conteúdo sejam nulos ou brancos, não
	 *             exista a sessão com o id informado ou não exista o
	 *             destinatário com o login informado, não exista a requisição
	 *             de empréstimo com o id informado ou o usuário da sessão não
	 *             participe deste empréstimo.
	 */
	public String enviarMensagem(String idSessao, String loginDestinatario,
			String assunto, String conteudoMensagem,
			String idRequisicaoEmprestimo) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (loginDestinatario == null || loginDestinatario.equals("")) {
			throw new Exception("Destinatário inválido");
		}
		if (assunto == null || assunto.equals("")) {
			throw new Exception("Assunto inválido");
		}
		if (conteudoMensagem == null || conteudoMensagem.equals("")) {
			throw new Exception("Mensagem inválida");
		}
		if (idRequisicaoEmprestimo == null || idRequisicaoEmprestimo.equals("")) {
			throw new Exception(
					"Identificador da requisição de empréstimo é inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario usuarioDestinatario = this.getUsuario(loginDestinatario);
			if (usuarioDestinatario == null) {
				throw new Exception("Destinatário inexistente");
			}
			RequisicaoDeEmprestimo requisicao = this
					.getRequisicaoEmprestimo(idRequisicaoEmprestimo);
			if (requisicao == null) {
				throw new Exception("Requisição de empréstimo inexistente");
			}
			if (!requisicao.getUsuario().equals(usuarioSessao)
					&& !requisicao.getItem().getUsuario().equals(usuarioSessao)) {
				throw new Exception("O usuário não participa deste empréstimo");
			}
			Mensagem mensagem = new Mensagem(usuarioSessao,
					usuarioDestinatario, conteudoMensagem);
			List<Usuario> usuariosTopico = new ArrayList<Usuario>();
			usuariosTopico.add(usuarioSessao);
			usuariosTopico.add(usuarioDestinatario);
			Topico topico = null;
			Iterator<Topico> it = this.topicos.iterator();
			boolean encontrouTopico = false;
			while (it.hasNext()) {
				Topico topicoIt = it.next();
				if (topicoIt.getAssunto().equals(assunto)
						&& topicoIt.getTipo().equals("negociacao")
						&& topicoIt.getUsuariosParticipantes().contains(
								usuarioSessao)
						&& topicoIt.getUsuariosParticipantes().contains(
								usuarioDestinatario)) {
					Topico topicoItmodificado = topicoIt;

					topicoItmodificado.addMensagem(mensagem);
					this.topicos.remove(topicoIt);
					this.topicos.add(topicoItmodificado);
					topico = topicoItmodificado;
					encontrouTopico = true;
					break;
				}
			}
			if (!encontrouTopico) {

				topico = new Topico(assunto, "negociacao", usuariosTopico);
				topico.addMensagem(mensagem);
				this.topicos.add(topico);
			}
			return topico.getId();
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Ler os tópico do usuário da sessão, do tipo informado
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário desejado
	 * @param tipo
	 *            O tipo dos tópico
	 * @return Os tópicos encontrados
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o tipo do tópico sejam
	 *             nulos ou brancos, não exista a sessão com o id informado ou
	 *             não sejam encontrados tópicos para o usuário e o tipo
	 *             informado.
	 */
	public String lerTopicos(String idSessao, String tipo) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (tipo == null || tipo.equals("")) {
			throw new Exception("Tipo inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<Topico> it = this.topicos.iterator();
			boolean encontrouTopico = false;
			String assuntoTopico = "";
			while (it.hasNext()) {
				Topico topicoIt = it.next();
				if (tipo.equals("todos")) {
					if (topicoIt.getUsuariosParticipantes().contains(
							usuarioSessao)) {
						if (assuntoTopico.equals("")) {
							assuntoTopico = topicoIt.getAssunto();
						} else {
							assuntoTopico = topicoIt.getAssunto() + "; "
									+ assuntoTopico;
						}
						encontrouTopico = true;
					}
				} else if (tipo.equals("negociacao") || tipo.equals("offtopic")) {
					if (topicoIt.getTipo().equals(tipo)
							&& topicoIt.getUsuariosParticipantes().contains(
									usuarioSessao)) {
						if (assuntoTopico.equals("")) {
							assuntoTopico = topicoIt.getAssunto();
						} else {
							assuntoTopico = topicoIt.getAssunto() + "; "
									+ assuntoTopico;
						}
						encontrouTopico = true;
					}
				} else {
					throw new Exception("Tipo inexistente");
				}
			}
			if (encontrouTopico) {
				return assuntoTopico;
			} else {
				return "Não há tópicos criados";
			}

		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Lê as mensagem para o usuário da sessão e que pertençam ao tópico
	 * informado.
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @param idTopico
	 *            O id do tópico
	 * @return As mensagens encontradas
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id do tópico sejam
	 *             nulos ou brancos, não exista a sessão com o id informado, o
	 *             tópico seja inexistente ou o usuário não tenha permissão para
	 *             ler as mensagens do tópico.
	 */
	public String lerMensagens(String idSessao, String idTopico)
			throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (idTopico == null || idTopico.equals("")) {
			throw new Exception("Identificador do tópico é inválido");
		}
		if (this.existeSessao(idSessao)) {
			Topico topico = this.getTopico(idTopico);
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			if (topico == null) {
				throw new Exception("Tópico inexistente");
			}
			if (!topico.getUsuariosParticipantes().contains(usuarioSessao)) {
				throw new Exception(
						"O usuário não tem permissão para ler as mensagens deste tópico");
			}
			Iterator<Mensagem> it = topico.getMensagens().iterator();
			String assuntoMensagem = "";
			while (it.hasNext()) {
				Mensagem mensagem = it.next();
				if (assuntoMensagem.equals("")) {
					assuntoMensagem = mensagem.getConteudo();
				} else {
					assuntoMensagem += "; " + mensagem.getConteudo();
				}
			}
			return assuntoMensagem;
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Retorna os amigos do usuário da sessão
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @return O login dos amigos do usuário da sessão
	 * @throws Exception
	 *             Lança exceção caso o id da sessão seja nulo ou branco.
	 */
	public String getAmigos(String idSessao) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			if (usuarioSessao.getAmigos().size() == 0) {
				return "O usuário não possui amigos";
			} else {
				Iterator<Usuario> it = usuarioSessao.getAmigos().iterator();
				String nomes = null;
				while (it.hasNext()) {
					Usuario amigo = it.next();
					if (nomes == null) {
						nomes = amigo.getLogin();
					} else {
						nomes += "; " + amigo.getLogin();
					}
				}
				return nomes;
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Retorna os amigos do usuário localizado a partir do login informado
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @param login
	 *            O login do usuário
	 * @return O login dos amigos do usuário localizado a partir do login
	 *         informado
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o login sejam nulos ou
	 *             brancos ou a sessão seja inexistente, o login seja
	 *             inexistente.
	 */
	public String getAmigos(String idSessao, String login) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (this.existeSessao(idSessao)) {
			// Usuario usuarioSessao =
			// this.localizarSessao(idSessao).getUsuario();
			Usuario usuarioLogin = this.getUsuario(login);
			if (usuarioLogin == null) {
				throw new Exception("Usuário inexistente");
			}
			if (usuarioLogin.getAmigos().size() == 0) {
				return "O usuário não possui amigos";
			} else {
				Iterator<Usuario> it = usuarioLogin.getAmigos().iterator();
				String nomes = null;
				while (it.hasNext()) {
					Usuario amigo = it.next();
					if (nomes == null) {
						nomes = amigo.getLogin();
					} else {
						nomes += "; " + amigo.getLogin();
					}
				}
				return nomes;
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Retorna Os itens do usuário da sessão
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @return Os itens do usuário da sessão
	 * @throws Exception
	 *             Lança exceção caso o id da sessão seja nulo ou branco ou a
	 *             sessão seja inexistente.
	 */
	public String getItens(String idSessao) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<Item> it = this.itens.iterator();
			String nomes = null;
			while (it.hasNext()) {
				Item item = it.next();
				if (item.getUsuario().equals(usuarioSessao)) {
					if (nomes == null) {
						nomes = item.getNome();
					} else {
						nomes += "; " + item.getNome();
					}
				}
			}
			if (nomes != null) {
				return nomes;
			} else {
				return "O usuário não possui itens cadastrados";
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Retorna Os itens do usuário localizado a partir do login
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @param login
	 *            O login do usuário
	 * @return Os itens do usuário localizado a partir do login
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o login sejam nulos ou
	 *             brancos, a sessão seja inexistente, o login seja inexistente,
	 *             o usuário não tenha permissão para visualizar os itens
	 */
	public String getItens(String idSessao, String login) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (login == null || login.equals("")) {
			throw new Exception("Login inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Usuario usuarioLogin = this.getUsuario(login);
			if (usuarioLogin == null) {
				throw new Exception("Usuário inexistente");
			}
			if (!usuarioSessao.getAmigos().contains(usuarioLogin)) {
				throw new Exception(
						"O usuário não tem permissão para visualizar estes itens");
			}
			Iterator<Item> it = this.itens.iterator();
			String nomes = null;
			while (it.hasNext()) {
				Item item = it.next();
				if (item.getUsuario().equals(usuarioLogin)) {
					if (nomes == null) {
						nomes = item.getNome();
					} else {
						nomes += "; " + item.getNome();
					}
				}
			}
			if (nomes != null) {
				return nomes;
			} else {
				return "O usuário não possui itens cadastrados";
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Retorna os empréstimos do usuário da sessão
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @param tipo
	 *            O tipo dos empréstimos
	 * @return Os empréstimos encontrados
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o tipo de empréstimo
	 *             sejam nulos ou brancos, a sessão seja inexistente, o tipo de
	 *             empréstimos seja inválido.
	 */
	public String getEmprestimos(String idSessao, String tipo) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (tipo == null || tipo.equals("")) {
			throw new Exception("Tipo inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<Emprestimo> it = this.emprestimos.iterator();
			String nomes = null;
			while (it.hasNext()) {
				Emprestimo emprestimo = it.next();
				if (tipo.equals("emprestador")) {
					if (emprestimo.getEmprestador().equals(usuarioSessao)) {
						if (nomes == null) {
							nomes = emprestimo.getEmprestador().getLogin()
									+ "-"
									+ emprestimo.getBeneficiado().getLogin()
									+ ":" + emprestimo.getItem().getNome();
							nomes += ":" + emprestimo.getSituacao();
						} else {
							nomes = emprestimo.getEmprestador().getLogin()
									+ "-"
									+ emprestimo.getBeneficiado().getLogin()
									+ ":" + emprestimo.getItem().getNome();
							nomes += ":" + emprestimo.getSituacao() + "; "
									+ nomes;
						}
					}
				} else if (tipo.equals("beneficiado")) {
					if (emprestimo.getBeneficiado().equals(usuarioSessao)) {
						if (nomes == null) {
							nomes = emprestimo.getEmprestador().getLogin()
									+ "-"
									+ emprestimo.getBeneficiado().getLogin()
									+ ":" + emprestimo.getItem().getNome();
							nomes += ":" + emprestimo.getSituacao();
						} else {
							nomes = emprestimo.getEmprestador().getLogin()
									+ "-"
									+ emprestimo.getBeneficiado().getLogin()
									+ ":" + emprestimo.getItem().getNome();
							nomes += ":" + emprestimo.getSituacao() + "; "
									+ nomes;
						}
					}
				} else if (tipo.equals("todos")) {
					if (emprestimo.getEmprestador().equals(usuarioSessao)
							|| emprestimo.getBeneficiado()
									.equals(usuarioSessao)) {
						if (nomes == null) {
							nomes = emprestimo.getEmprestador().getLogin()
									+ "-"
									+ emprestimo.getBeneficiado().getLogin()
									+ ":" + emprestimo.getItem().getNome();
							nomes += ":" + emprestimo.getSituacao();
						} else {
							String nome = emprestimo.getEmprestador()
									.getLogin()
									+ "-"
									+ emprestimo.getBeneficiado().getLogin()
									+ ":" + emprestimo.getItem().getNome();
							nome = nome + ":" + emprestimo.getSituacao();
							if (emprestimo.getEmprestador().equals(
									usuarioSessao)) {
								nomes = nome + "; " + nomes;
							} else {
								nomes += "; " + nome;
							}
						}
					}
				} else {
					throw new Exception("Tipo inexistente");
				}
			}
			if (nomes != null) {
				return nomes;
			} else {
				return "Não há empréstimos deste tipo";
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Cria uma requisição de empréstimo
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário requisitante
	 * @param idItem
	 *            O id do item
	 * @param duracao
	 *            A duaração do empréstimo
	 * @return O id da nova requisição de empréstimo
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id do item sejam nulos
	 *             ou brancos, a duração seja menor ou igual a 1, o item seja
	 *             inexistente, o usuário não seja amigo do dono do item ou a
	 *             requisição já tenha sido solicitada.
	 */
	public String requisitarEmprestimo(String idSessao, String idItem,
			int duracao) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (idItem == null || idItem.equals("")) {
			throw new Exception("Identificador do item é inválido");
		}
		if (duracao < 1) {
			throw new Exception("Duracao inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Item item = this.getItem(idItem);
			if (item == null) {
				throw new Exception("Item inexistente");
			}

			if (!usuarioSessao.getAmigos().contains(item.getUsuario())) {
				throw new Exception(
						"O usuário não tem permissão para requisitar o empréstimo deste item");
			}

			RequisicaoDeEmprestimo requisicao = new RequisicaoDeEmprestimo(
					usuarioSessao, item, duracao);
			if (this.contemRequisicaoEmprestimo(requisicao)) {
				throw new Exception("Requisição já solicitada");
			}
			this.requisicoesEmprestimo.add(requisicao);
			String assuntoTopico = "Empréstimo do item " + item.getNome()
					+ " a " + usuarioSessao.getNome();
			List<Usuario> usuariosTopico = new ArrayList<Usuario>();
			usuariosTopico.add(usuarioSessao);
			usuariosTopico.add(item.getUsuario());
			Topico topico = new Topico(assuntoTopico, "negociacao",
					usuariosTopico);
			String assuntoMensagem = usuarioSessao.getNome()
					+ " solicitou o empréstimo do item " + item.getNome();
			Mensagem mensagem = new Mensagem(usuarioSessao, item.getUsuario(),
					assuntoMensagem);
			topico.addMensagem(mensagem);
			this.topicos.add(topico);
			return requisicao.getId();
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Cria um interesse pelo item
	 * 
	 * @param idSessao
	 *            O id da sessão contendo o usuário interessado
	 * @param idItem
	 *            O id do item
	 * @throws Exception
	 *             Lança exceção caso o id da sessão ou o id do item sejam nulos
	 *             ou brancos, o item seja inexistente, o usuário não seja amigo
	 *             do dono do item, o usuário interessado seja dono do item ou o
	 *             interesse já tenha sido solicitado.
	 */
	public void registrarInteresse(String idSessao, String idItem)
			throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (idItem == null || idItem.equals("")) {
			throw new Exception("Identificador do item é inválido");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Item item = this.getItem(idItem);
			if (item == null) {
				throw new Exception("Item inexistente");
			}
			if (item.getUsuario().equals(usuarioSessao)) {
				throw new Exception(
						"O usuário não pode registrar interesse no próprio item");
			}
			if (!usuarioSessao.getAmigos().contains(item.getUsuario())) {
				throw new Exception(
						"O usuário não tem permissão para registrar interesse neste item");
			}
			Interesse interesse = new Interesse(usuarioSessao, item);
			if (this.contemInteresse(interesse)) {
				throw new Exception(
						"O usuário já registrou interesse neste item");
			}
			Usuario usuario = usuarioSessao;
			usuario.addAtividade(usuario.getNome()+ " tem interesse pelo item "+item.getNome()+" de "+item.getUsuario().getNome(),item.getUsuario());
			interesse.setUsuario(usuario);
			this.usuarios.remove(usuarioSessao);
			this.usuarios.add(usuario);
			this.interesses.add(interesse);
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Localiza uma sessão a partir do id informado
	 * 
	 * @param idSessao
	 *            O id da sessaão
	 * @return retorna a sessão localizada a partir do id
	 */
	public Sessao localizarSessao(String idSessao) {
		Iterator<Sessao> it = this.sessoes.iterator();
		while (it.hasNext()) {
			Sessao sessao = it.next();
			if (sessao.getId().equals(idSessao)) {
				return sessao;
			}
		}
		return null;
	}

	/**
	 * Retorna a data do sistema
	 * 
	 * @return Retorna a data do sistema
	 */
	public static Calendar getDataSistema() {
		return Sistema.dataSitema;
	}

	/**
	 * Adiciona dias à data do sistema
	 * 
	 * @param numeroDias
	 *            O número de dias a ser adicionados
	 */
	public static void adicionarDias(int numeroDias) {
		Sistema.dataSitema.add(Calendar.DATE, 7);
		Sistema.dataSitema.clear(Calendar.MILLISECOND);
	}

	/**
	 * Retorna os itens encontrados a partir dos dados fornecidos
	 * 
	 * @param idSessao
	 *            O id da sessão
	 * @param chave
	 *            A chave da busca
	 * @param atributo
	 *            O atributo desejado
	 * @param tipoOrdenacao
	 *            O tipo de ordenação - crecente ou decrescente
	 * @param criterioOrdenacao
	 *            O critério de ordenação - data de criação ou reputação do
	 *            usuário dono do item
	 * @return A lista com os nomes dos itens
	 * @throws Exception
	 * 			Lança exceção caso o id da sessão ou, a chave, o atributo, o 
	 * 			tipo de ordenação ou o critério de ordenação sejam nulos
	 *             ou brancos, o item seja inexistente, o tipo ou critério de 
	 *             ordenação sejam inexistente ou o item seja inexistente.
	 */
	public String pesquisarItem(String idSessao, String chave, String atributo,
			String tipoOrdenacao, String criterioOrdenacao) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			if (chave == null || chave.equals("")) {
				throw new Exception("Chave inválida");
			}
			if (atributo == null || atributo.equals("")) {
				throw new Exception("Atributo inválido");
			}
			if (!(atributo.equals("nome") || atributo.equals("descricao") || atributo
					.equals("categoria"))) {
				throw new Exception("Atributo inexistente");
			}
			if (tipoOrdenacao == null || tipoOrdenacao.equals("")) {
				throw new Exception("Tipo inválido de ordenação");
			}
			if (!(tipoOrdenacao.equals("crescente") || tipoOrdenacao
					.equals("decrescente"))) {
				throw new Exception("Tipo de ordenação inexistente");
			}
			if (criterioOrdenacao == null || criterioOrdenacao.equals("")) {
				throw new Exception("Critério inválido de ordenação");
			}
			if (!(criterioOrdenacao.equals("dataCriacao") || criterioOrdenacao
					.equals("reputacao"))) {
				throw new Exception("Critério de ordenação inexistente");
			}

			Collection<Item> itensOrdenados = null;
			if (criterioOrdenacao.equals("dataCriacao")) {
				itensOrdenados = this.ordenarItensPorData(usuarioSessao,
						tipoOrdenacao);
			} else {
				itensOrdenados = this.ordenarItensPorReputacao(usuarioSessao,
						tipoOrdenacao);
			}

			List<String> itensEncontrados = new ArrayList<String>();
			Iterator<Item> it = itensOrdenados.iterator();
			while (it.hasNext()) {

				Item item = it.next();

				if (atributo.equals("nome")) {
					if (item.getNome().toLowerCase().contains(
							chave.toLowerCase())) {
						itensEncontrados.add(item.getNome());
					}
				} else if (atributo.equals("descricao")) {
					if (item.getDescricao().toLowerCase().contains(
							chave.toLowerCase())) {
						itensEncontrados.add(item.getNome());
					}
				} else {
					if (item.getCategoria().toLowerCase().contains(
							chave.toLowerCase())) {
						itensEncontrados.add(item.getNome());
					}
				}
			}
			Iterator<String> it2 = itensEncontrados.iterator();
			String nomesItens = "";
			while (it2.hasNext()) {
				String item = it2.next();
				if (nomesItens.equals("")) {
					nomesItens += item;
				} else {
					nomesItens += "; " + item;
				}
			}

			if (nomesItens.equals("")) {
				return "Nenhum item encontrado";
			}

			return nomesItens;
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Desfaz uma amizade
	 * @param idSessao O id da sessão contendo o usuário que deseja desfazer a amizade
	 * @param amigo O login do amigo
	 * @throws Exception Lança exceção caso o id da sessão ou o login sejam nulos
	 *             ou brancos, o usuário ou a amizade sejam inexistentes.
	 */
	public void desfazerAmizade(String idSessao, String amigo) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			if (!this.existeSessao(idSessao)) {
				throw new Exception("Sessão inexistente");
			}
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			if (amigo == null || amigo.equals("")) {
				throw new Exception("Login inválido");
			}
			Usuario usuarioAmigo = this.getUsuario(amigo);
			if (usuarioAmigo == null) {
				throw new Exception("Usuário inexistente");
			}
			if (this.ehAmigo(idSessao, amigo).equals("false")) {
				throw new Exception("Amizade inexistente");
			}
			List<Usuario> amigosUsuarioSessao = usuarioSessao.getAmigos();
			List<Usuario> amigosUsuarioAmigo = usuarioAmigo.getAmigos();
			Usuario usuarioTemp1 = usuarioSessao;
			Usuario usuarioTemp2 = usuarioAmigo;
			amigosUsuarioSessao.remove(usuarioTemp2);
			amigosUsuarioAmigo.remove(usuarioTemp1);
			usuarioSessao.setAmigos(amigosUsuarioSessao);
			usuarioAmigo.setAmigos(amigosUsuarioAmigo);

			Iterator<RequisicaoDeEmprestimo> it = this.requisicoesEmprestimo
					.iterator();
			while (it.hasNext()) {
				RequisicaoDeEmprestimo requisicao = it.next();
				String loginRequisitante = requisicao.getUsuario().getLogin();
				String loginDonoItem = requisicao.getItem().getUsuario()
						.getLogin();
				if ((loginRequisitante.equals(usuarioSessao.getLogin()) && loginDonoItem
						.equals(usuarioAmigo.getLogin()))
						|| (loginRequisitante.equals(usuarioAmigo.getLogin()) && loginDonoItem
								.equals(usuarioSessao.getLogin()))) {
					this.requisicoesEmprestimo.remove(requisicao);
					break;
				}
			}
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/**
	 * Apaga um item do sistema
	 * @param idSessao O id da sessão contendo o dono do item
	 * @param idItem O id do item
	 * @throws Exception Lança exceção caso o id da sessão ou o id do item sejam nulos
	 *             ou brancos, a sessão seja inexistente, o item seja inexistente, o 
	 *             usuário não seja o dono do tem ou item esteja emprestado.
	 */
	public void apagarItem(String idSessao, String idItem) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			if (!this.existeSessao(idSessao)) {
				throw new Exception("Sessão inexistente");
			}
			if (idItem == null || idItem.equals("")) {
				throw new Exception("Identificador do item é inválido");
			}
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			Iterator<Item> it = this.itens.iterator();
			Item itemEncontrado = null;
			while (it.hasNext()) {
				Item item = it.next();
				if (item.getId().equals(idItem)) {
					itemEncontrado = item;
					break;
				}
			}
			if (itemEncontrado == null) {
				throw new Exception("Item inexistente");
			}
			if (!itemEncontrado.getUsuario().equals(usuarioSessao)) {
				throw new Exception(
						"O usuário não tem permissão para apagar este item");
			}
			if (itemEncontrado.getSituacao().equals("Emprestado")) {
				throw new Exception(
						"O usuário não pode apagar este item enquanto estiver emprestado");
			}
			Iterator<RequisicaoDeEmprestimo> itReq = this.requisicoesEmprestimo
					.iterator();
			while (itReq.hasNext()) {
				RequisicaoDeEmprestimo requisicao = itReq.next();
				if (requisicao.getItem().equals(itemEncontrado)) {
					this.requisicoesEmprestimo.remove(requisicao);
					break;
				}
			}
			this.itens.remove(itemEncontrado);
		} else {
			throw new Exception("Sessão inexistente");
		}
	}
	
	/**
	 * Retorna a lista de usuários ranqueados de acordo com a cateogira do ranking informada
	 * @param idSessao O id da Sessão
	 * @param categoria A caegoria do ranking
	 * @return A lista de usuários
	 * @throws Exception Lança exceção caso o id da sessão ou a caegoria sejam nulos
	 *             ou brancos, a sessão seja inexistente ou a categoria seja inexistene, 
	 */
	public String getRanking(String idSessao, String categoria) throws Exception {
		if (idSessao == null || idSessao.equals("")) {
			throw new Exception("Sessão inválida");
		}
		if (this.existeSessao(idSessao)) {
			if (!this.existeSessao(idSessao)) {
				throw new Exception("Sessão inexistente");
			}
			if (categoria == null || categoria.equals("")) {
				throw new Exception("Categoria inválida");
			}
			if (!categoria.equals("global") && !categoria.equals("amigos")) {
				throw new Exception("Categoria inexistente");
			}
			Usuario usuarioSessao = this.localizarSessao(idSessao).getUsuario();
			SortedMap<Integer,String> rankingEmprestimosOrdenado = this.ordenaMapaEmprestimos();
			Iterator<Integer> it = rankingEmprestimosOrdenado.keySet().iterator();
			String nomes = "";
			while(it.hasNext()){
				Integer chave = it.next();
				String valor = rankingEmprestimosOrdenado.get(chave);
				if(categoria.equals("global")){
					if(nomes.equals("")){
						nomes = valor;
					}else{
						nomes = valor+"; "+nomes;
					}
				}else{
					if(valor.equals(usuarioSessao.getLogin()) || this.ehAmigo(idSessao, valor).equals("true")){
						if(nomes.equals("")){
							nomes = valor;
						}else{
							nomes = valor+"; "+nomes;
						}
					}
				}
				
			}
			return nomes;
		} else {
			throw new Exception("Sessão inexistente");
		}
	}

	/*
	 * ---------------------------------------------------------
	 * ---------------------MÉTODOS PRIVADOS--------------------
	 * ---------------------------------------------------------
	 */

	/**
	 * Remove o interesse pelo item
	 * 
	 * @param usuario O usuário interessado
	 * @param item O item desejado
	 */
	private void removerInteresse(Usuario usuario, Item item) {
		Iterator<Interesse> it = this.interesses.iterator();
		while (it.hasNext()) {
			Interesse interesse = it.next();
			if (interesse.getUsuario().equals(usuario)
					&& interesse.getItem().equals(item)) {
				this.interesses.remove(interesse);
				break;
			}
		}
	}

	/**
	 * Remove uma requisição de empréstimo
	 * @param idRequisicao O id da requisição
	 */
	private void removerRequisicaoEmprestimo(String idRequisicao) {
		Iterator<RequisicaoDeEmprestimo> it = this.requisicoesEmprestimo
				.iterator();
		while (it.hasNext()) {
			RequisicaoDeEmprestimo requisicao = it.next();
			if (requisicao.getId().equals(idRequisicao)) {
				this.requisicoesEmprestimo.remove(requisicao);
				break;
			}
		}

	}

	/**
	 * Envia uma mensagem de interesse
	 * @param item O item desejado
	 */
	private void enviarMensagemInteresse(Item item) {
		Iterator<Interesse> it = this.interesses.iterator();
		while (it.hasNext()) {
			Interesse interesse = it.next();
			if (interesse.getItem().equals(item)) {
				Topico topico = new Topico("O item " + item.getNome()
						+ " do usuário " + item.getUsuario().getNome()
						+ " está disponível", "offtopic", item.getUsuario(),
						interesse.getUsuario());
				if (!this.contemTopico(topico)) {
					Mensagem mensagem = new Mensagem(item.getUsuario(),
							interesse.getUsuario(),
							"Agora você pode requisitar o empréstimo do "
									+ item.getNome());
					topico.addMensagem(mensagem);
					this.topicos.add(topico);
				}
			}
		}
	}

	/**
	 * Verifica a existencia de um tópico
	 * @param _topico O tópico a ser testado
	 * @return
	 */
	private boolean contemTopico(Topico _topico) {
		Iterator<Topico> it = this.topicos.iterator();
		while (it.hasNext()) {
			Topico topico = it.next();
			if (topico.getAssunto().equals(_topico.getAssunto())
					&& topico.getUsuariosParticipantes().equals(
							_topico.getUsuariosParticipantes())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Envia mensagem de requisição de devolução
	 * @param emprestimo O empréstimo que contem requisitado
	 * @throws Exception Lança exceção inerente ao envio da mensagem
	 */
	private void enviarMensagemRequisicaoDevolucao(Emprestimo emprestimo)
			throws Exception {
		String assuntoTopico = "Empréstimo do item "
				+ emprestimo.getItem().getNome() + " a "
				+ emprestimo.getBeneficiado().getNome();
		Topico topico = this.getTopicoByAssunto(assuntoTopico);
		Topico topicoAlterado = null;
		if (topico == null) {
			topicoAlterado = new Topico(assuntoTopico, "negociacao", emprestimo
					.getEmprestador(), emprestimo.getBeneficiado());
		} else {
			topicoAlterado = topico;
		}

		String conteudoMensagem = emprestimo.getEmprestador().getNome()
				+ " solicitou a devolução do item "
				+ emprestimo.getItem().getNome();
		Mensagem mensagem = new Mensagem(emprestimo.getEmprestador(),
				emprestimo.getBeneficiado(), conteudoMensagem);
		topicoAlterado.addMensagem(mensagem);
		this.topicos.remove(topico);
		this.topicos.add(topicoAlterado);
	}

	/**
	 * Remove uma requisição de amizade
	 * @param requisitante O usuário requisitante
	 * @param requisitado O usuário requisitado
	 */
	private void removerRequisicaoAmizade(Usuario requisitante,
			Usuario requisitado) {
		Iterator<RequisicaoDeAmizade> it = this.requisicoes.iterator();
		while (it.hasNext()) {
			RequisicaoDeAmizade requisicao = it.next();
			if (requisicao.getRequisitante().equals(requisitante)
					&& requisicao.getRequisitado().equals(requisitado)) {
				this.requisicoes.remove(requisicao);
				break;
			}
		}
	}

	/**
	 * Verifica se contem uma requisição de amizade
	 * @param _requisicao A requisição a ser testada
	 * @return True ou False
	 */
	private boolean contemRequisicao(RequisicaoDeAmizade _requisicao) {
		Iterator<RequisicaoDeAmizade> it = this.requisicoes.iterator();
		while (it.hasNext()) {
			RequisicaoDeAmizade requisicao = it.next();
			if (requisicao.getRequisitante().equals(
					_requisicao.getRequisitante())
					&& requisicao.getRequisitado().equals(
							_requisicao.getRequisitado())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Vereifica se contem um interesse
	 * @param _interesse O interesse a ser testado
	 * @return Retorna True ou False
	 */
	private boolean contemInteresse(Interesse _interesse) {
		Iterator<Interesse> it = this.interesses.iterator();
		while (it.hasNext()) {
			Interesse interesse = it.next();
			if (interesse.getUsuario().equals(_interesse.getUsuario())
					&& interesse.getItem().equals(_interesse.getItem())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Verifica se contem um empréstimo
	 * @param _emprestimo O empréstimo a ser testado
	 * @return True ou False
	 */
	private boolean contemEmprestimo(Emprestimo _emprestimo) {
		Iterator<Emprestimo> it = this.emprestimos.iterator();
		while (it.hasNext()) {
			Emprestimo emprestimo = it.next();
			if (emprestimo.getId().equals(_emprestimo.getId())
					|| (emprestimo.getEmprestador().equals(
							_emprestimo.getEmprestador())
							&& emprestimo.getBeneficiado().equals(
									_emprestimo.getBeneficiado())
							&& emprestimo.getItem().equals(
									_emprestimo.getItem()) && emprestimo
							.getDuracao() == _emprestimo.getDuracao())) {
				if (!emprestimo.getSituacao().equals("Completado")) {
					return true;
				}

			}
		}
		return false;
	}

	/**
	 * Verifica se contem uma requisição de empréstimo
	 * @param _requisicao A requisição a ser testada
	 * @return True ou False
	 */
	private boolean contemRequisicaoEmprestimo(
			RequisicaoDeEmprestimo _requisicao) {
		Iterator<RequisicaoDeEmprestimo> it = this.requisicoesEmprestimo
				.iterator();
		while (it.hasNext()) {
			RequisicaoDeEmprestimo requisicao = it.next();
			if (requisicao.getUsuario().equals(_requisicao.getUsuario())
					&& requisicao.getItem().equals(_requisicao.getItem())
					&& requisicao.getDuracao() == _requisicao.getDuracao()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Verifica a existencia de uma sessão
	 * @param idSessao O id da sessão
	 * @return True ou False
	 */
	private boolean existeSessao(String idSessao) {
		Iterator<Sessao> it = this.sessoes.iterator();
		while (it.hasNext()) {
			Sessao sessao = it.next();
			if (sessao.getId().equals(idSessao)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Retorna um usuário a partir do login
	 * @param login O login do usuário
	 * @return O usuário ou null, caso o usuário não exista
	 */
	private Usuario getUsuario(String login) {
		Iterator<Usuario> it = this.usuarios.iterator();
		while (it.hasNext()) {
			Usuario usuario = it.next();
			if (usuario.getLogin().equals(login)) {
				return usuario;
			}
		}
		return null;
	}

	/**
	 * Retorna um empréstimo a partir do Id
	 * @param idEmprestimo O id do empréstimo
	 * @return O empréstimo ou null, caso o empréstimo não exista
	 */
	private Emprestimo getEmprestimo(String idEmprestimo) {
		Iterator<Emprestimo> it = this.emprestimos.iterator();
		while (it.hasNext()) {
			Emprestimo emprestimo = it.next();
			if (emprestimo.getId().equals(idEmprestimo)) {
				return emprestimo;
			}
		}
		return null;
	}

	/**
	 * Retorna um item a partir do Id
	 * @param idItem O id do item
	 * @return O Item ou null, caso o item não exista
	 */
	private Item getItem(String idItem) {
		Iterator<Item> it = this.itens.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (item.getId().equals(idItem)) {
				return item;
			}
		}
		return null;
	}

	/**
	 * Retorna uma requisição de empréstimo a partir do Id
	 * @param idRequisicaoEmprestimo O id da requisição
	 * @return A requisição de empréstimo ou null, caso a requisição não exista
	 */
	private RequisicaoDeEmprestimo getRequisicaoEmprestimo(String idRequisicaoEmprestimo) {
		Iterator<RequisicaoDeEmprestimo> it = this.requisicoesEmprestimo
				.iterator();
		while (it.hasNext()) {
			RequisicaoDeEmprestimo requisicao = it.next();
			if (requisicao.getId().equals(idRequisicaoEmprestimo)) {
				return requisicao;
			}
		}
		return null;
	}

	/**
	 * Retorna um tópico a partir do Id
	 * @param idTopico O id do tópico
	 * @return Retorna o tópico ou null, caso não exista
	 */
	private Topico getTopico(String idTopico) {
		Iterator<Topico> it = this.topicos.iterator();
		while (it.hasNext()) {
			Topico topico = it.next();
			if (topico.getId().equals(idTopico)) {
				return topico;
			}
		}
		return null;
	}

	/**
	 * Retorna um tópico a partir do assunto
	 * @param assunto O assunto do tópico
	 * @return Retona o tópico ou null, caso não exista
	 */
	private Topico getTopicoByAssunto(String assunto) {
		Iterator<Topico> it = this.topicos.iterator();
		while (it.hasNext()) {
			Topico topico = it.next();
			if (topico.getAssunto().equals(assunto)) {
				return topico;
			}
		}
		return null;
	}

	/**
	 * Retorna uma lista dos itens dos amigos do usuário ordenados por data de criação
	 * @param usuarioOrdem O usuário
	 * @param tipo O tipo de ordenação: crescente ou decrescente
	 * @return
	 */
	private List<Item> ordenarItensPorData(Usuario usuarioOrdem, String tipo) {
		Iterator<Item> itOrdem = this.itens.iterator();
		SortedMap<Calendar, Item> itensOrdenadosData = new TreeMap<Calendar, Item>();
		while (itOrdem.hasNext()) {
			Item itemData = itOrdem.next();
			if (usuarioOrdem.getAmigos().contains(itemData.getUsuario())) {
				if (itensOrdenadosData.containsKey(itemData.getDataCriacao())) {
					itemData.getDataCriacao().add(Calendar.MILLISECOND, 1);
				}
				itensOrdenadosData.put(itemData.getDataCriacao(), itemData);
			}
		}
		Item[] itensArray = new Item[itensOrdenadosData.size()];
		itensOrdenadosData.values().toArray(itensArray);
		List<Item> listItem = new ArrayList<Item>();
		if (tipo.equals("crescente")) {
			for (int k = 0; k < itensArray.length; k++) {
				listItem.add(itensArray[k]);
			}
		} else {
			for (int k = itensArray.length - 1; k >= 0; k--) {
				listItem.add(itensArray[k]);
			}
		}
		return listItem;
	}

	/**
	 * Retorna uma lista dos itens dos amigos do usuário ordenados por reputação do usuário
	 * @param usuarioOrdem O usuário
	 * @param tipo O tipo de ordenação: crescente ou decrescente
	 * @return
	 */
	private List<Item> ordenarItensPorReputacao(Usuario usuario, String tipo) {
		Iterator<Item> it = this.itens.iterator();
		SortedMap<String, Item> itensOrdenadosPorReputacao = new TreeMap<String, Item>();
		while (it.hasNext()) {
			Item item2 = it.next();
			itensOrdenadosPorReputacao.put(this.getReputacao(usuario, item2),
					item2);
		}
		Item[] itensArrayReputacao = new Item[itensOrdenadosPorReputacao.size()];
		itensOrdenadosPorReputacao.values().toArray(itensArrayReputacao);
		List<Item> listItem = new ArrayList<Item>();
		if (tipo.equals("crescente")) {
			for (int k = 0; k < itensArrayReputacao.length; k++) {
				listItem.add(itensArrayReputacao[k]);
			}
		} else {
			for (int k = itensArrayReputacao.length - 1; k >= 0; k--) {
				listItem.add(itensArrayReputacao[k]);
			}
		}
		return listItem;
	}

	/**
	 * Retorna a reputação do usuário: número de empréstimos completados como emprestador
	 * @param usuario O usuário a ser pesquisado
	 * @param item O item a ser pesquisado
	 * @return A reputação do usuário
	 */
	private String getReputacao(Usuario usuario, Item item) {
		Iterator<Emprestimo> it = this.emprestimos.iterator();
		int reputacao = 0;
		while (it.hasNext()) {
			Emprestimo emprestimo = it.next();
			if (emprestimo.getItem().equals(item)
					&& emprestimo.getItem().getUsuario().getAmigos().contains(
							usuario)) {
				reputacao++;
			}
		}
		return new Integer(reputacao).toString();
	}

	/**
	 * Retorna uma requisição de amizade a partir dos usuários requisitante e requisitado
	 * @param requisitante O usuário requisitante
	 * @param requisitado O usuário requisitado
	 * @return A requisição de amizade ou null caso não exista
	 */
	private RequisicaoDeAmizade getRequisicaoDeAmizade(Usuario requisitante,
			Usuario requisitado) {
		Iterator<RequisicaoDeAmizade> it = this.requisicoes.iterator();
		while (it.hasNext()) {
			RequisicaoDeAmizade requisicao = it.next();
			if (requisicao.getRequisitante().equals(requisitante)
					&& requisicao.getRequisitado().equals(requisitado)) {
				return requisicao;
			}
		}
		return null;
	}
	
	/**
	 * Retorna uma mapa de empréstimo ordenados pela quantidade de emprestimos de cada usuário
	 * @return O mapa ordenado
	 */
	private SortedMap<Integer, String> ordenaMapaEmprestimos() {
		
		SortedMap<Integer, String> mapaEmprestimosRanqueado = new TreeMap<Integer,String>();
		Set<String> chaves = this.mapaEmprestimos.keySet();
		Iterator<String> it = chaves.iterator();
		while(it.hasNext()){
			
			String chave = it.next();
			Integer valor = this.mapaEmprestimos.get(chave);
			mapaEmprestimosRanqueado.put(valor, chave);

		}
		return mapaEmprestimosRanqueado;
	}

}